
package com.tools;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.regex.Pattern;

import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;


public class MysqlPagination implements Pagination {

	private int pageSize = 20;
	private int pageNumber = 1;// 当前页码
	private int maxPages = 0;
	private int maxElements = 0;
	private String sql;
	private MysqlUtil db;
	
	
	public MysqlPagination(String sql) {
		this.sql = sql;
	}

	public MysqlPagination(int pageSize, int pageNumber, String sql) {
		this.pageSize = pageSize;
		this.pageNumber = pageNumber;
		this.sql = sql;
	}

	public void init() {
		db = new MysqlUtil("java:/comp/env/jdbc/ds_mysql");
		db.init();
		setMaxElements();
		setMaxPages();
	}
	
	public void setMaxElements() {
		// select * from xxx order by desc
		// select count(*) from xxx order by desc
		String regex = "select ((.)+) from";
		Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
		String[] s = p.split(this.sql);
		String newSql = "select count(1) as total from" + s[1];
		ResultSetHandler handler = new ResultSetHandler() {
			public Object handle(ResultSet rs) throws SQLException {
				if (rs.next()) {
					return new Integer(rs.getInt("total"));
				} else {
					return null;
				}
			}
		};
		this.maxElements = (Integer) db.query(newSql, null, handler);
	}

	public void setMaxPages() {
		if (maxElements != 0 && (maxElements % pageSize == 0)) {
			this.maxPages = maxElements / pageSize;
		} else {
			this.maxPages = maxElements / pageSize + 1;
		}
	}
	
	private String sqlModify(String source, int begin, int end) {
		StringBuffer target = new StringBuffer(200);
		target.append("select * from (select a.*, rownum r from (");
		target.append(sql);
		target.append(") a where rownum <=");
		target.append(end);
		target.append(") where r>=");
		target.append(begin);
		return target.toString();
	}
	
	private int getEndElement() {
		int endElement = pageNumber * pageSize;
		if (endElement >= maxElements) {
			return maxElements;
		} else {
			return endElement;
		}
	}

	private int getBeginElement() {
		return (pageNumber - 1) * pageSize + 1;
	}
	
	@Override
	public boolean isFirst() {
		return pageNumber == 1;
	}

	@Override
	public boolean isLast() {
		return pageNumber >= this.getMaxPages();
	}

	@Override
	public boolean hasNext() {
		return pageNumber < this.getMaxPages();
	}

	@Override
	public boolean hasPrevious() {
		return pageNumber > 1;
	}

	@Override
	public int getMaxElements() {
		return maxElements;
	}

	@Override
	public int getMaxPages() {
		return maxPages;
	}

	@Override
	public int getNext() {
		if (pageNumber + 1 >= this.maxPages) {
			return getMaxPages();
		} else {
			return pageNumber + 1;
		}
	}

	@Override
	public int getPrevious() {
		if (pageNumber - 1 <= 1) {
			return 1;
		} else {
			return pageNumber - 1;
		}
	}

	@Override
	public int getPageSize() {
		return pageSize;
	}

	@Override
	public int getPageNumber() {
		return pageNumber;
	}

	@Override
	public List<Object> getList() {
		String newSql = this.sqlModify(this.sql, this.getBeginElement(),this.getEndElement());
		return (List) db.query(newSql, null, new MapListHandler());
	}

	@Override
	public void setPageSize(int pageSize) {
		// TODO Auto-generated method stub

	}

	@Override
	public void setPageNumber(int pageNumber) {
		// TODO Auto-generated method stub

	}

}
